package com.qaplus.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.qaplus.annotation.SystemErrorLog;
import com.qaplus.annotation.SystemOperatorLog;
import com.qaplus.common.CommonBusiLogic;
import com.qaplus.constant.Common;
import com.qaplus.constant.CommonBoolean;
import com.qaplus.constant.JobType;
import com.qaplus.constant.TaskContent;
import com.qaplus.entity.QaAttachment;
import com.qaplus.entity.QaClass;
import com.qaplus.entity.QaTask;
import com.qaplus.entity.QaUser;
import com.qaplus.entity.QaUserExample;
import com.qaplus.entity.QaUserTask;
import com.qaplus.entity.vo.ClassStuZTreeVo;
import com.qaplus.entity.vo.Page;
import com.qaplus.entity.vo.ResponseData;
import com.qaplus.mapper.QaUserMapperExt;
import com.qaplus.service.AttachmentService;
import com.qaplus.service.ClassService;
import com.qaplus.service.TaskService;
import com.qaplus.service.UserService;
import com.qaplus.service.UserTaskService;
import com.qaplus.utils.DateFormatPatterns;
import com.qaplus.utils.EncryptUtil;
import com.qaplus.utils.FileUtil;
import com.qaplus.utils.LongUtil;
import com.qaplus.utils.SuperDate;

@Service
public class UserServiceImpl implements UserService {
	private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

	@Resource
	private QaUserMapperExt userMapperExt;
	@Resource
	private TaskService taskService;
	@Resource
	private UserTaskService userTaskService;
	@Resource
	private ClassService classService;
	@Resource
	private AttachmentService attachmentService;

	private static final String DELEMITER = ",";
	private static final String STU_TREE_PRFIX = "STU_";
	private static final String TEA_TREE_PREFIX = "TEA_";

	@Override
	public QaUser userLogin(String username, String password) {
		QaUser user = userMapperExt.userLogin(username);
		return (null != user && user.getPassword().equals(password)) ? user : null;
	}

	@SystemErrorLog(description = "用户注册失败")
	@SystemOperatorLog(description = "用户注册")
	@Override
	public QaUser userRegister(QaUser regUser) {
		// 刚刚注册时没有用的数据，需要教师或学生确认后才有用
		regUser.setIsDeleted(CommonBoolean.Y.name());
		try {
			regUser.setPassword(EncryptUtil.encrypt(regUser.getPassword()));
		} catch (Exception e) {
			logger.error("密码加密失败", e);
		}
		regUser.setHasIcon(CommonBoolean.N.name());
		regUser.setClassId(DELEMITER + regUser.getClassId() + DELEMITER);
		dispatchTask(regUser);
		userMapperExt.insertSelective(regUser);
		return regUser;
	}

	/**
	 * 提醒相关人员有用户注册了
	 * @param regUser
	 */
	private void dispatchTask(QaUser regUser){
		QaClass clazz = classService.selectByPrimary(Long.parseLong(regUser.getClassId()));
		// 让同学或者老师审批
		QaTask task = new QaTask();
		task.setOperKey(TaskContent.USER_REGISTER.getValue());
		task.setTriggerPerson(regUser.getUsername());
		// 分配任务
		// 学生-同班同学或者老师审批
		List<QaUser> users = new ArrayList<QaUser>();
		if (regUser.getJob() == JobType.STU.getValue()) {
			QaUserExample example = new QaUserExample();
			example.createCriteria().andClassIdLike("%" + DELEMITER + regUser.getClassId() + DELEMITER + "%");
			users = userMapperExt.selectByExample(example);

			task.setContent("[" + TaskContent.USER_REGISTER.getDesc() + "]  用户：" + regUser.getUsername() + "，在" + SuperDate.format(new Date(), DateFormatPatterns.DATETIME_PATTERN_YYYYMMDDHHMMSS) + " 申请成为："
					+ clazz.getName() + "的学生");
			
			// 老师-所有老师审批
		} else if (regUser.getJob() == JobType.TEA.getValue()) {
			QaUserExample example = new QaUserExample();
			example.createCriteria().andJobEqualTo(JobType.TEA.getValue());
			users = userMapperExt.selectByExample(example);

			task.setContent("[" + TaskContent.USER_REGISTER.getDesc() + "]  用户：" + regUser.getUsername() + "，在" + SuperDate.format(new Date(), DateFormatPatterns.DATETIME_PATTERN_YYYYMMDDHHMMSS) + " 申请管理："
					+ clazz.getName() + "的学生，成为老师");
		}
		task.setKeyword(regUser.getUsername());
		taskService.addTask(task);

		for (QaUser qaUser : users) {
			QaUserTask record = new QaUserTask();
			record.setTaskId(task.getId());
			record.setUserId(qaUser.getId());
			userTaskService.addUserTask(record);
		}
	}
	
	@Cacheable(value="user")
	@Override
	public QaUser queryTeacher(Long id) {
		// 查询某个学生的老师
		// TODO 没有考虑一个学生有多个老师的情况下
		return userMapperExt.queryTeacher(id);
	}

	/**
	 * 获得用户数组
	 */
	// TODO 记得把分页加上，记得考虑有搜索条件的时候（可以使用你的参数user考虑搜索条件）
	@Override
	public ResponseData<QaUser> getUserList(Page page, QaUser user) {
		if (page != null && page.getEnd() == 0) {
			CommonBusiLogic.setPageBeginByPage(page);
		}
		return new ResponseData<QaUser>(userMapperExt.getUserList(user.getId()), userMapperExt.countForPage());// userMapperExt.countForPage()
	}

	@Override
	public List<QaUser> selectAllTeacher() {
		return userMapperExt.selectAllTeacher();
	}

	@Override
	public int updateByPrimaryKeySelective(QaUser record) {
		return userMapperExt.updateByPrimaryKeySelective(record);
	}

	@Override
	public QaUser queryById(Long id) {
		return userMapperExt.selectByPrimaryKey(id);
	}

	@Override
	public List<QaUser> selectAllStusByTeacherId(Long teacherId) {
		QaUser teacher = userMapperExt.selectByPrimaryKey(teacherId);
		String classes[] = teacher.getClassId().split(DELEMITER);
		List<QaUser> allStudents = new ArrayList<QaUser>();
		for (String classId : classes) {
			List<QaUser> oneClassStudent = selectAllStusByClassId(Long.parseLong(classId));
			allStudents.addAll(oneClassStudent);
		}
		return allStudents;
	}

	@Override
	public List<QaUser> selectAllStusByClassId(Long classId) {
		QaUserExample example = new QaUserExample();
		example.createCriteria().andIsDeletedEqualTo(CommonBoolean.N.name()).andJobEqualTo(1).andClassIdLike("%" + DELEMITER + classId + DELEMITER + "%");
		return userMapperExt.selectByExample(example);
	}

	@Override
	public List<ClassStuZTreeVo> buildClassStuZTree() {
		QaUser user = this.getCurrentUserBySession();
		QaUser teacher = userMapperExt.selectByPrimaryKey(user.getId());
		String classes[] = teacher.getClassId().split(DELEMITER);

		List<ClassStuZTreeVo> tree = new ArrayList<ClassStuZTreeVo>();

		for (String classId : classes) {
			if (StringUtils.isEmpty(classId)) {
				continue;
			}
			ClassStuZTreeVo zTreeClass = new ClassStuZTreeVo();
			zTreeClass.setParentId("0");
			QaClass clazz = classService.selectByPrimary(Long.parseLong(classId));
			if (null != clazz) {
				zTreeClass.setName(clazz.getName());
				zTreeClass.setOpen(true);
				zTreeClass.setTreeId(classId);
				tree.add(zTreeClass);

				List<QaUser> oneClassStudent = selectAllStusByClassId(Long.parseLong(classId));
				for (QaUser student : oneClassStudent) {
					ClassStuZTreeVo zTreeStudent = new ClassStuZTreeVo();
					zTreeStudent.setParentId(classId);
					zTreeStudent.setName(student.getName());
					zTreeStudent.setOpen(true);
					/** 切记：treeId一定不能一样，找了好久才找到，原谅第一次使用ztree **/
					zTreeStudent.setTreeId(STU_TREE_PRFIX + student.getId());
					tree.add(zTreeStudent);
				}
			}
		}
		return tree;
	}

	@Override
	public List<ClassStuZTreeVo> buildAllUserTree() {
		List<QaClass> classes = classService.selectAllClasses();
		List<ClassStuZTreeVo> tree = new ArrayList<ClassStuZTreeVo>();

		for (QaClass qaClass : classes) {
			ClassStuZTreeVo zTreeClass = new ClassStuZTreeVo();
			zTreeClass.setParentId("0");
			zTreeClass.setName(qaClass.getName());
			zTreeClass.setOpen(true);
			zTreeClass.setTreeId(qaClass.getId().toString());
			tree.add(zTreeClass);

			List<QaUser> oneClassUser = selectAllUserByClassId(Long.parseLong(qaClass.getId().toString()));

			for (QaUser qaUser : oneClassUser) {
				ClassStuZTreeVo zTreeUser = new ClassStuZTreeVo();
				zTreeUser.setParentId(qaClass.getId().toString());
				zTreeUser.setName(qaUser.getName());
				zTreeUser.setOpen(true);
				/** 切记：treeId一定不能一样，找了好久才找到，原谅第一次使用ztree **/
				if (JobType.TEA.getValue().equals(qaUser.getJob())) {
					zTreeUser.setTreeId(TEA_TREE_PREFIX + qaUser.getId());
				} else {
					zTreeUser.setTreeId(STU_TREE_PRFIX + qaUser.getId());
				}
				tree.add(zTreeUser);
			}

		}
		return tree;
	}

	// 用户名唯一
	@Override
	public QaUser queryIsDeletedUserByUsername(String username) {
		return userMapperExt.queryIsDeletedUserByUsername(username);
	}

	@Override
	public int updateIsDeletedUserCanUser(Long id) {
		return userMapperExt.updateIsDeletedUserCanUser(id);
	}

	@Override
	public QaUser getCurrentUserBySession() {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		HttpSession session = request.getSession();
		QaUser user = (QaUser) session.getAttribute(Common.CURRENT_OPERATOR.getValue());
		if (user == null) {
			throw new RuntimeException("用户没有登录，获取不到用户信息，请登录");
		} else {
			return user;
		}
	}

	private QaUser setCurrentUserInSession(QaUser user) {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		HttpSession session = request.getSession();
		session.removeAttribute(Common.CURRENT_OPERATOR.getValue());
		session.setAttribute(Common.CURRENT_OPERATOR.getValue(), user);
		return user;
	}

	@Override
	public QaUser checkUsername(String username) {
		return userMapperExt.checkUsername(username);
	}

	@Override
	public QaUser updateUserInfo(QaUser user) {
		if (LongUtil.isNotNull(user.getAttachmentId())) {
			user.setHasIcon(CommonBoolean.Y.name());
		} 
		if(StringUtils.isEmpty(user.getPassword())){
			user.setPassword(null);
		}else{
			user.setPassword(EncryptUtil.encrypt(user.getPassword()));
		}
		userMapperExt.updateByPrimaryKeySelective(user);
		QaUser updatedUser = userMapperExt.selectByPrimaryKey(user.getId());
		setCurrentUserInSession(updatedUser);
		return updatedUser;
	}

	@Override
	public List<QaUser> selectAllUserByClassId(Long classId) {
		QaUserExample example = new QaUserExample();
		example.createCriteria().andIsDeletedEqualTo(CommonBoolean.N.name()).andClassIdLike("%" + DELEMITER + classId + DELEMITER + "%");
		example.setOrderByClause(" job desc");
		return userMapperExt.selectByExample(example);
	}

	@Override
	public List<QaUser> queryUncommitHomeworkUser(Long homeworkId) {
		return userMapperExt.queryHomeworkUser(homeworkId, CommonBoolean.N.name());
	}

	@Override
	public List<QaUser> queryHomeworkUsers(Long homeworkId) {
		return userMapperExt.queryHomeworkUser(homeworkId, null);
	}

	@Override
	public List<QaUser> queryCommitHomeworkUser(Long homeworkId) {
		return userMapperExt.queryHomeworkUser(homeworkId, CommonBoolean.Y.name());
	}

	@Override
	public void previewImg(HttpServletResponse response) {
		QaUser user = this.getCurrentUserBySession();
		if(CommonBoolean.N.name().equals(user.getHasIcon())){
			return ;
		}else if(CommonBoolean.Y.name().equals(user.getHasIcon())){
			QaAttachment attachment=attachmentService.queryById(Long.parseLong(user.getAttachmentId().toString()));
			try {
				FileUtil.pageImgTagView(response, attachment.getAttachmentPath().substring(0, attachment.getAttachmentPath().length()-1));
			} catch (Exception e) {
				logger.error("查看头像失败",e);
			}
		}
	}
}